package com.asp.aspchain.core.ethereum;

import java.io.IOException;
import java.math.BigInteger;
import java.util.List;

import org.junit.Test;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.response.EthAccounts;
import org.web3j.protocol.core.methods.response.EthBlock.Block;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.geth.Geth;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import rx.Subscription;

public class App {

	public EthService ethService = new EthService();

	// GAS价格  
	public BigInteger GAS_PRICE = BigInteger.valueOf(20_000_000_000L);
	// GAS上限  
	public BigInteger GAS_LIMIT = BigInteger.valueOf(4_300_000L);

	// 交易费用  
	public BigInteger GAS_VALUE = BigInteger.valueOf(1300_000L);

	public static void main(String[] args) {
		// 获取余额
		/*
		 * try { System.out.println("Hello World!"); Admin admin =
		 * EthService.initAdmin();
		 * System.out.println(admin.personalListAccounts().send().getAccountIds()); ////
		 * ShhAddToGroup group = admin.shhAddToGroup(
		 * "enode://6d1819c68ad4bb4928f349d8fecb14223087b4ea0740dd3ffee55b95d975c2123d230e12e13a40083fc902440d83f0aa17e0a925616110c14273e6b2d7f59635@192.168.1.64:30303"
		 * ).send(); //// System.out.println(group); // // NetPeerCount
		 * count=admin.netPeerCount().send(); // System.out.println(count.getResult());
		 * } catch (IOException e) { // TODO Auto-generated catch block
		 * e.printStackTrace(); }
		 */
	}

	/**
	 * 开始挖矿
	 */
	@Test
	public void startMining() {

	}

	/**
	 * 新建用户
	 */
	@Test
	public void CreateNewAccounts() {
		String account = "";
		try {
			account = ethService.newAccount("123456");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(account);
	}

	/**
	 * 获取钱包里的所有用户
	 */
	@Test
	public void getAllAccounts() {
		try {
			Geth geth = ethService.initGeth();
			Request<?, EthAccounts> request = geth.ethAccounts();
			List<String> list = request.send().getAccounts();
			System.out.println(list.toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 获取用户余额
	 */
	@Test
	public void getAccountBalance() {
		try {
			String address = "0xdbaea9b9d0b4d9dfff546466c89de34c9711a942";// 0x8b7483ea3c7a545dbf93bf07764b479e0469e821
																			// 0xdbaea9b9d0b4d9dfff546466c89de34c9711a942
			Web3j web3 = ethService.initWeb3j();
			EthGetBalance ethGetBalance1 = web3.ethGetBalance(address, DefaultBlockParameter.valueOf("latest")).send();
			System.out.println(ethGetBalance1.getBalance());
			System.out.println(
					address + "的余额:" + Convert.fromWei(ethGetBalance1.getBalance().toString(), Convert.Unit.ETHER)); // .new
																														// BigDecimal(ethGetBalance1.getBalance()
																														// +
																														// "").divide(BigDecimal.valueOf(Math.pow(10,
																														// 18))).setScale(6)
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 转账
	 */
	@Test
	public void transferBalance() {
		try {
			boolean flag = ethService.unlockAccount("0xdbaea9b9d0b4d9dfff546466c89de34c9711a942", "123456",
					new BigInteger(1800 + ""));
			System.out.println(flag);

			BigInteger value = Convert.toWei("12", Convert.Unit.ETHER).toBigInteger();

			Web3j web3j = ethService.initWeb3j();
			Credentials credentials = WalletUtils.loadCredentials("123456",
					"F:\\Ethereum\\blockchain\\keystore\\UTC--2018-04-26T06-04-02.691651400Z--dbaea9b9d0b4d9dfff546466c89de34c9711a942");

			// get the next available nonce
			BigInteger nonce = ethService.getNonce("0xdbaea9b9d0b4d9dfff546466c89de34c9711a942");

			// create our transaction
			RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, GAS_PRICE, GAS_LIMIT,
					"0x8b7483ea3c7a545dbf93bf07764b479e0469e821", value);

			// sign & send our transaction
			byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
			String hexValue = Numeric.toHexString(signedMessage);
			EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();

			System.out.println(ethSendTransaction.getResult());
			System.out.println(ethSendTransaction.getTransactionHash());

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 监听新区块
	 */
	@Test
	public void observableBlockChain() {
		Web3j web3j = ethService.initWeb3j();
		Subscription subscription = web3j.blockObservable(false).subscribe(block -> {
			Block blk = block.getResult();
			System.out.println("当前区块高度：" + blk.getNumber() + ",上一个区块：" + blk.getParentHash() + blk.getHash());
		});
		System.out.println("订阅的" + subscription.hashCode());
	}

}
